const Router = require('koa-router')
const User = require('../../models/user')
// 封装bcrypt依赖用于加密和解密密码
const toolBcrypt = require('../../config/toolBcrypt')
// 用于查询全球通用头像
const gravatar = require('gravatar')
// 重点!! token!! 登陆成功后返回token
const jwt = require('jsonwebtoken')
// 将jwt.sign()第二个参数分开存放
const secretKey = require('../../config/keys').secretKey
// 网上找到这个依赖使用貌似更加方便 这里换这个依赖进行token验证
const koaJwt = require('koa-jwt')

const router = new Router()

/**
 * @method POST
 * @route /user/register
 * @data  account password email
 * @description 用于注册
 */
router.post('/register', async ctx => {
  if (ctx.request.body) {
    const { body } = ctx.request
    const findRes = await User.find({ email: body.email })
    if (findRes.length) {
      ctx.status = 500
      ctx.body = { msg: '该用户已经存在' }
    } else {
      // 这里获取全球通用头像 https://www.npmjs.com/package/gravatar
      // 第一个参数是邮箱地址 第二个参数是选项 s代表大小 r不知道  d表示默认 如果查询不到就为默认 具体的看网址
      const avatar = gravatar.url(body.email, { s: '200', r: 'pg', d: 'mm' })

      // 这里创建新用户
      const newUser = new User({
        ...body,
        password: toolBcrypt.enCrypt(body.password),
        avatar
      })
      console.log(newUser)
      await newUser.save().then((res) => {
        console.log(res, '创建成功')
        ctx.status = 200
        ctx.body = newUser
      }).catch((err) => {
        console.log(err, '创建错误')
        ctx.status = 500
        ctx.body = { msg: err }
      })
    }
  } else {
    ctx.status = 403
    ctx.body = { msg: '请传入数据' }
  }

})

/**
 * @method POST
 * @route /user/login
 * @param email password
 * @description 用于登录
 */
router.post('/login', async ctx => {
  const { body } = ctx.request
  // 注意 与数据库沟通的形为都是异步的!  所以要使用await
  // find() 返回数组  findOne 找到就返回对象 没有找到就返回null
  const findRes = await User.findOne({ email: body.email })
  console.log(findRes)
  // 如果存在的话就验证密码
  if (findRes) {
    const flag = toolBcrypt.checkCrypt(body.password, findRes.password)
    if (flag) {
      // 定于需要给前端返回什么数据  等下要存放在token中
      const payload = {
        id: findRes.id,
        name: findRes.username,
        avatar: findRes.avatar
      }
      // 根据阮一峰的jwt讲解  生成的token 由三部分 1. header 头部 2. payload 负载 3. Signature 签名
      // jwt.sign() 这个函数用于生成token  可以传入四个参数 前两个参数必须
      // 第一个参数就是负载 第二个参数是签名?暂时不知道它的作用 第三个参数 是选项比如过期时间,
      // 加密算法这些;第四个参数是回调函数  这里过期时间为3600s  一个小时
      const token = jwt.sign(payload, secretKey, { expiresIn: 3600 })

      ctx.status = 200
      // !注意这里返回token一定要'Bearer '+产生的token  这是规定 就算这里不加 前端发送到后端时也需要添加
      ctx.body = { token: 'Bearer ' + token }
    } else {
      ctx.status = 500
      ctx.body = { msg: 'wrong', name: 'password' }
    }
  } else {
    ctx.status = 500
    ctx.body = {
      msg: 'not fount',
      name: 'user'
    }
  }
})

/**
 * @method GET
 * @route /user/current
 * @param token
 * @description 用于查询当前登录的用户信息 需要token验证
 */
router.get('/current', koaJwt({ secret: secretKey }), async ctx => {
  // 注意 通过token严重后  会将解密后的payload放在ctx.state.user中
  // 如果使用koaJwt({ secret: secretKey, key: 'data' }) 那么就会放到 ctx.state.data中
  console.log(ctx.state.user)

  const payload = ctx.state.user

  // 这里要加await  而且mongoose默认的id键名是 _id
  const user = await User.findOne({ _id: payload.id })
  // console.log(payload,user)
  ctx.body = { success: true, data: user }
})

module.exports = router.routes()
